package com.foton.servletdemo.controller;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import sun.misc.Contended;

import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author RenPu
 * @Date 2023/3/15 18:02
 * @Version 1.0
 * @Description:
 **/


@RestController
public class DerredResultController {

    @Contended   //避免伪共享的注解
    private String nii;

    //定义一个容器用来储存当请求量比较大时存储异步对象
    private  LinkedBlockingQueue<DeferredResult> queue=new LinkedBlockingQueue<>();

    //自定义线程池，防止线程爆炸式增长，统一管理
    private static ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(100,200,500L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(500));


    @RequestMapping("/get")
    public DeferredResult get(){

        final DeferredResult<String> deferredResult=new DeferredResult<>(100L);
        queue.add(deferredResult);

        poolExecutor.submit(()->{
            try {
                Random random = new Random();
                int time = random.nextInt(1000);    //从十秒钟范围，随机选择一个时间进行睡眠
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("模拟处理业务代码。。。。。。");
            String returnVlaue="返回值。。。。。";
            deferredResult.setResult(returnVlaue);

        });


        //当达到设置的超时间的阀值，进行触发此方法进行服务降级
        deferredResult.onTimeout(()->{

            //TODO 根据自己的业务逻辑进行设置自己的降级业务处理
            System.out.println("当前系统繁忙，请稍后在尝试。。。。。。。。");
            deferredResult.setResult("超时的返回结果。。。。。。。");
        });


      deferredResult.onCompletion(()->{
          System.out.println("任务执行完成后，需要DeferredResult从队列里进行remove。。。。。。。。");
         queue.remove(deferredResult);
      });

       return deferredResult;
    }




    //定时任务进行定期查看

    @Scheduled(fixedRate = 1000)
    public void shcheldTask(){

        for (int i = 0; i <queue.size() ; i++) {
            DeferredResult<String> dR = queue.poll();
            dR.setResult("result: "+i);
        }




    }






}
